package com.myopen.interceptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.myopen.config.ConstConfig;
import com.myopen.model.Resource;
import com.myopen.model.Role;
import com.myopen.model.User;

public class AdminInterceptor implements Interceptor{

	private static Map<String,Record> urls=null;
	private static Map<String,Record> codes=null;
	private static Map<String,Record> ignoreUrls=null;
	
	@Override
	public void intercept(Invocation me) {
		
		//首先判断是否当前路径需要跳过验证
		//然后判断当前路径是否在权限配置的URLS里面，如果不在里面，那么跳过验证
		//然后如果当前路径在权限URLS里面，那么进行权限验证，验证通过，继续执行，验证不过通过，跳转到登录页面。
		
		
		if(urls==null||codes==null||ignoreUrls==null){
			//如果任意一个值为空，那么重新从数据库取值
			List<Record> resources=Resource.dao.getAllResources();
			urls=new HashMap<>();
			codes=new HashMap<>();
			ignoreUrls=new HashMap<>();
			
			for (Record record : resources) {
				if(StrKit.notBlank(record.getStr("url"))){
					urls.put(Resource.formatUrl(record.getStr("url")), record);
				}
				codes.put(record.getStr("code"), record);
			}
			
			String ignoreUrlsStr=PropKit.get("auth.url.verify.skip");
			String[] ignoreUrlsStrs=ignoreUrlsStr.split(",");
			for (String string : ignoreUrlsStrs) {
				if(StrKit.notBlank(string)){
					ignoreUrls.put(string, new Record());
				}
			}
		}
		
		String actionKey=Resource.formatUrl(me.getActionKey());
		//记录一下当前用户的菜单
		if(urls.containsKey(actionKey)) {
			me.getController().setSessionAttr(ConstConfig.SESSION_MENU_OPEN_CODE, urls.get(actionKey));
		}
		
		
		
		if(ignoreUrls.containsKey(actionKey)){
			me.invoke();
		}else{
			
			Record currUser=me.getController().getSessionAttr(ConstConfig.SESSION_ADMIN_USER);
			//特殊认证，数据源权限查看,如果没有权限的暂时不用跳转就行
			if(actionKey.contains("druid")){
				if(currUser!=null){
					if(User.hasAuthCode("druid", currUser)){
						me.invoke();
					}
				}
			}
			
			
			if(urls.containsKey(actionKey)){
				//如果当前路径包含在了需要验证的路径当中,那么需要认证
				if(currUser==null){
					me.getController().redirect("/admin/login");
				}else{
					
					Map<String,Record> sessionResourceUrls=currUser.get(ConstConfig.SESSION_ADMIN_RESOURCE_URLS);
					Map<String,Record> sessionResourceCodes=currUser.get(ConstConfig.SESSION_ADMIN_RESOURCE_CODES);
					List<Record> sessionMenus=currUser.get(ConstConfig.SESSION_ADMIN_MENUS);
					
					if(sessionResourceCodes==null||sessionResourceUrls==null||sessionMenus==null){
						
						//此时可以判断是首次登录，可以把登录日志保存在数据库
						
						sessionResourceUrls=new HashMap<>();
						sessionResourceCodes=new HashMap<>();
						sessionMenus=new ArrayList<>();
						
						String roleId=currUser.getStr("roleId");
						Record role=Role.dao.getRecordById(roleId);
						List<Record> sessionResources=Resource.dao.getRecordsByRoleId(roleId);
						
						//此处有个逻辑，如果role的角色为超级管理员，那么超级管理员具有所有的权限,后期可能在数据库配置
						if("admin".equals(role.getStr("code"))){
							sessionResources=Resource.dao.getAllResources();
						}
						
						for (Record record : sessionResources) {
							if(StrKit.notBlank(record.getStr("url"))){
								sessionResourceUrls.put(Resource.formatUrl(record.getStr("url")), record);
							}
							sessionResourceCodes.put(record.getStr("code"), record);
						}
						
						sessionMenus=getMenus(sessionResources);
						
						currUser.set(ConstConfig.SESSION_ADMIN_ROLE, role);
						currUser.set(ConstConfig.SESSION_ADMIN_MENUS, sessionMenus);
						currUser.set(ConstConfig.SESSION_ADMIN_RESOURCE_URLS, sessionResourceUrls);
						currUser.set(ConstConfig.SESSION_ADMIN_RESOURCE_CODES, sessionResourceCodes);
						
						me.getController().setSessionAttr(ConstConfig.SESSION_ADMIN_USER, currUser);
					}
					
					if(sessionResourceUrls.containsKey(actionKey)){
						me.invoke();
					}else{
						me.getController().redirect("/admin/login");
					}
				}
			}else{
				me.invoke();
			}
			
		}
		
	}
	
	private List<Record> getMenus(List<Record> resources){
		List<Record> menus=new ArrayList<>();
		
		for (Record record : resources) {
			if("0".equals(record.getStr("visibility"))){
				if(StrKit.isBlank(record.getStr("parentId"))){
					menus.add(record);
				}
			}
		}
		
		for (Record m : menus) {
			
			List<Record> childrens=new ArrayList<>();
			for (Record record : resources) {
				if("0".equals(record.getStr("visibility"))){
					if(m.getStr("id").equals(record.getStr("parentId"))){
						childrens.add(record);
					}
				}
			}
			m.set("childrens", childrens);
		}
		
		return menus;
		
	}
	
}
